package com.tyl.xtk.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tyl.xtk.beans.po.User;
import com.tyl.xtk.beans.query.LoginForm;
import com.tyl.xtk.beans.vo.LoginResult;
import com.tyl.xtk.beans.vo.Result;
import com.tyl.xtk.config.PasswordEncoder;
import com.tyl.xtk.constants.CacheConst;
import com.tyl.xtk.exception.ServiceException;
import com.tyl.xtk.mapper.UserMapper;
import com.tyl.xtk.service.UserService;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * create by tyl at 2025/8/27
 */
@Service
public class UserServiceImpl extends DataServiceImpl<UserMapper,User> implements UserService {


    @Resource
    PasswordEncoder passwordEncoder;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;


    @Override
    public Result<LoginResult> login(LoginForm loginForm) {
        // 验证验证码
        String captcha = loginForm.getCaptcha();
        String uuid = loginForm.getUuid();
        
        if (StringUtils.isBlank(uuid)) {
            return Result.fail("缺少验证码标识");
        }
        
        if (StringUtils.isBlank(captcha)) {
            return Result.fail("请输入验证码");
        }
        
        String redisKey = CacheConst.CAPTCHA_PREFIX + uuid;
        String redisCaptcha = (String) redisTemplate.opsForValue().get(redisKey);
        
        if (redisCaptcha == null) {
            return Result.fail("验证码已过期");
        }
        
        // 删除已使用的验证码
        redisTemplate.delete(redisKey);
        
        if (!captcha.equalsIgnoreCase(redisCaptcha)) {
            return Result.fail("验证码错误");
        }
        
        User user = baseMapper.selectOne(new QueryWrapper<User>().lambda().eq(User::getUsername, loginForm.getUsername()));
        if (user == null) {
            return Result.fail("用户名或密码错误！");
        }
        if (!passwordEncoder.matches(loginForm.getPassword(), user.getPassword())) {
            return Result.fail("用户名或密码错误");
        }
        StpUtil.login(user.getId());
        StpUtil.getSession().set("user", user);
        LoginResult loginResult = new LoginResult();
        loginResult.setToken(StpUtil.getTokenValue());
        loginResult.setUser(user);
        return Result.success(loginResult);
    }


    @Override
    public boolean logout() {
        StpUtil.logout();
        return true;
    }

    @Override
    public User selectCurrentUser() {
        long loginId = StpUtil.getLoginIdAsLong();
        return baseMapper.selectById(loginId);

    }

    @Override
    public List<com.tyl.xtk.beans.po.Role> selectRoleListByUserId(long userId) {
        return baseMapper.selectRoleListByUserId(userId);
    }

    @Transactional
    @Override
    public Result<User> register(User user) {
        try {
            boolean success = insertUser(user);
            if (success) {
                return Result.success(user);
            } else {
                return Result.fail("注册失败");
            }
        } catch (ServiceException e) {
            return Result.fail(e.getMessage());
        }
    }

    @Transactional
    public boolean update(User user) {
        /// 不更新密码字段
        user.setPassword(null);
        if (StringUtils.isNotBlank(user.getUsername()) && baseMapper.exists(new QueryWrapper<User>().lambda().eq(User::getUsername, user.getUsername()).ne(User::getId, user.getId()))) {
            throw new ServiceException("用户名已存在");
        }
        
        // 检查手机号是否已存在
        if (StringUtils.isNotBlank(user.getPhone()) && 
            baseMapper.exists(new QueryWrapper<User>().lambda().eq(User::getPhone, user.getPhone()).ne(User::getId, user.getId()))) {
            throw new ServiceException("手机号已被注册");
        }
        
        return baseMapper.updateById(user) > 0;
    }

    /**
     * 统一用户创建逻辑
     * @param user 用户信息
     * @return 是否创建成功
     */
    private boolean insertUser(User user) {
        // 检查用户名是否已存在
        if (baseMapper.exists(new QueryWrapper<User>().lambda().eq(User::getUsername, user.getUsername()))) {
            throw new ServiceException("用户已存在");
        }
        
        // 注册时额外检查邮箱是否已存在
        if (StringUtils.isNotBlank(user.getEmail()) &&
            baseMapper.exists(new QueryWrapper<User>().lambda().eq(User::getEmail, user.getEmail()))) {
            throw new ServiceException("邮箱已被注册");
        }
        
        // 检查手机号是否已存在
        if (StringUtils.isNotBlank(user.getPhone()) && 
            baseMapper.exists(new QueryWrapper<User>().lambda().eq(User::getPhone, user.getPhone()))) {
            throw new ServiceException("手机号已被注册");
        }
        
        // 对密码进行加密
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        
        // 插入用户数据
        return baseMapper.insert(user) > 0;
    }
    
    @Override
    public void saveCaptchaToRedis(String uuid, String captcha) {
        String redisKey = CacheConst.CAPTCHA_PREFIX + uuid;
        redisTemplate.opsForValue().set(redisKey, captcha, 5, TimeUnit.MINUTES);
    }
}